
#include <map>
#include <boost/date_time.hpp>
#include "DebugStream.h"

namespace Engine {

	CDebugStream DebugStream;

	CDebugStream& CDebugStream::write( const char *text )
	{
		boost::thread::id id = boost::this_thread::get_id();
		map<boost::thread::id, std::string>::iterator i = mBuffers.find(id);
		if(i == mBuffers.end()) {
			mBuffers[id] = string();
			i = mBuffers.find(id);
		}

		i->second.append(text);

		int rpos = strlen(text)-1;
		if(text[rpos] == '\n' || text[rpos] == '\r') {
			cout << i->second;
			i->second.clear();
		}

		return *this;
	}

	CDebugStream& CDebugStream::writeCurrentTime()
	{
		boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
		return write(boost::posix_time::to_iso_string(now).c_str());
	}

	CDebugStream& CDebugStream::operator <<( bool v )
	{
		const char *out = v ? "true" : "false";
		return write(out);
	}

	CDebugStream& CDebugStream::operator <<( short v )
	{
		char buffer[64];
		sprintf( buffer, "%hd", v );
		return write( buffer );
	}

	CDebugStream& CDebugStream::operator <<( unsigned short v )
	{
		char buffer[64];
		sprintf( buffer, "%hu", v );
		return write( buffer );
	}

	CDebugStream& CDebugStream::operator <<( int v )
	{
		char buffer[64];
		sprintf( buffer, "%d", v );
		return write( buffer );
	}

	CDebugStream& CDebugStream::operator <<( unsigned int v )
	{
		char buffer[64];
		sprintf( buffer, "%u", v );
		return write( buffer );
	}

	CDebugStream& CDebugStream::operator <<( long v )
	{
		char buffer[64];
		sprintf( buffer, "%ld", v );
		return write( buffer );
	}

	CDebugStream& CDebugStream::operator <<( unsigned long v )
	{
		char buffer[64];
		sprintf( buffer, "%lu", v );
		return write( buffer );
	}

	CDebugStream& CDebugStream::operator <<( float v )
	{
		char buffer[128];
		sprintf( buffer, "%.16g", double(v) );
		return write( buffer );
	}

	CDebugStream& CDebugStream::operator <<( double v )
	{
		char buffer[128];
		sprintf( buffer, "%.16g", v );
		return write( buffer );
	}

	CDebugStream& CDebugStream::operator <<( long double v )
	{
		char buffer[128];
		sprintf( buffer, "%.16g", double(v) );
		return write( buffer );
	}

	CDebugStream& CDebugStream::operator <<( const void *v )
	{
		char buffer[64];
		sprintf( buffer, "%p", v );
		return write( buffer );
	}

	CDebugStream& CDebugStream::operator <<( const char *v )
	{
		return write( v ? v : "NULL" );
	}

	CDebugStream& CDebugStream::operator <<( char c )
	{
		char buffer[16];
		sprintf( buffer, "%c", c );
		return write( buffer );
	}

	CDebugStream& CDebugStream::operator <<( const std::string &s )
	{
		return write( s.c_str());
	}
}
